package cn.tedu.luban.order.main.controler;

import cn.tedu.luban.order.common.enums.OrderResultEnum;
import cn.tedu.luban.order.main.converter.OrderConverter;
import cn.tedu.luban.order.main.service.OrderService;
import cn.tedu.luban.order.protocol.VO.FrontOrderDetailVO;
import cn.tedu.luban.order.protocol.VO.FrontOrderItemVO;
import cn.tedu.luban.order.protocol.bo.OrderBO;
import cn.tedu.luban.order.protocol.param.OrderConfirmParam;
import cn.tedu.luban.order.protocol.param.OrderCreateParam;

import cn.tedu.luban.order.protocol.param.OrderFinishParam;
import cn.tedu.luban.order.protocol.param.OrderSignParam;
import cn.tedu.luban.order.protocol.query.FrontOrderListQuery;
import cn.tedu.luban.passport.protocol.jwt.UserPrinciple;
import cn.tedu.luban.passport.sdk.security.LubanSecurityContext;
import cn.tedu.luban.worker.common.enums.WorkerResultEnum;
import com.tedu.inn.protocol.ListRecordTotalBO;
import com.tedu.inn.protocol.exception.BusinessException;
import com.tedu.inn.protocol.model.Result;
import com.tedu.inn.protocol.pager.PagerResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RestController
@Slf4j
public class OrderController {

    @Autowired
    private OrderService orderService;
    /*
    StringRedisTemplate、 RedisTemplate
    类型限制：
    StringRedisTemplate<String, String>、RedisTemplate<String, Object>
     */
    @Autowired
    private StringRedisTemplate redisTemplate;

    @PostMapping("/order/create")
    public Result<String> createOrder(@RequestBody OrderCreateParam param) throws BusinessException {

        //频繁抢单的拦截
        reGrabIntercept(param);

        //进入业务
        String orderNo = orderService.createOrder(param);

        return new Result<>(orderNo);
    }

    /**
     * 频繁抢单的拦截
     */
    private void reGrabIntercept(OrderCreateParam param) throws BusinessException {
        // 拿到userId
        UserPrinciple user = LubanSecurityContext.getLoginToken();
        // 不一定拿到登录用户
        if(user == null){
            throw new BusinessException(WorkerResultEnum.USER_TOKEN_VERIFY_FAILED);
        }
        Long userId = user.getId();
        // 补充userId(后续service也可以补充)
        param.setUserId(userId);

        // 需求单的编号
        String requestOrderNo = param.getRequestOrderNo();

        // 设计key userId:requestOrderNo
        String regrabKey ="luban:order:regrab:" + userId + ":" + requestOrderNo;

        ValueOperations<String, String> opsForValue = redisTemplate.opsForValue();
        Long increment = opsForValue.increment(regrabKey);
        redisTemplate.expire(regrabKey, 3, TimeUnit.SECONDS);
        // 判断incr结果>1 true的话都拦截，频繁抢单
        if(increment>1){
            log.error("频繁抢单拦截：userId={},requestOrderNo={}",userId,requestOrderNo);
            throw new BusinessException(OrderResultEnum.ORDER_RE_GRAB);
        }
    }


    @Autowired
    private OrderConverter orderConverter;

    /**
     * 未完成订单列表
     */
    @PostMapping("/order/list")
    public Result<PagerResult<FrontOrderItemVO>> orderList(
            @RequestBody FrontOrderListQuery query) throws BusinessException{

        ListRecordTotalBO<OrderBO> listBO = orderService.orderList(query);

        PagerResult<FrontOrderItemVO> pagerResult = orderConverter.assemblePagerResult(listBO, query);

        return new Result<>(pagerResult);
    }


    /**
     * 订单详情
     */
    @GetMapping("/order/info")
    public Result<FrontOrderDetailVO> orderInfo(String orderNo) throws BusinessException{
        OrderBO orderBO = orderService.orderInfo(orderNo);
        FrontOrderDetailVO vo = orderConverter.bo2frontDetailVO(orderBO);
        return new Result<>(vo);
    }

    /**
     * 订单签到
     */
    @PostMapping("/order/sign")
    public Result<String> orderSign(@RequestBody OrderSignParam param) throws BusinessException{
        // 进入业务
        orderService.orderSign(param);
        // 正常返回值数据
        return new Result<>(param.getOrderNo());
    }


    /**
     * 施工确认（施工图片绑定）
     */
    @PostMapping("/order/confirm")
    public Result<String> orderConfirm(@RequestBody OrderConfirmParam param) throws BusinessException{
        // 进入业务
        orderService.orderConfirm(param);
        // 正常返回值数据
        return new Result<>(param.getOrderNo());
    }

    /**
     * 师傅点击完成订单（接口完成后，订单实际状态：完成未结算 30，订单真正完成 40）
     */
    @PostMapping("/order/finish")
    public Result<String> orderFinish(@RequestBody OrderFinishParam param) throws BusinessException{
        orderService.orderFinish(param);
        return new Result<>(param.getOrderNo());
    }
}
